const { ccclass, property } = cc._decorator;
@ccclass
export default class Handler {
    static _gid: number = 1;
    static _pool = [];

    public _id: number = 0;
    public caller: any;
    public method: Function;
    public args: any[];
    public once: boolean = false;

    constructor(caller: any = null, method: Function = null, args: any[] = null, once: boolean = false) {
        this.setTo(caller, method, args, once);
    }

    register(e, t) {
     
    }

    check(e, t) {
    }

    public setTo(t, a, o, i) {
        void 0 === i && (i = false);
        this._id = Handler._gid++;
        this.caller = t;
        this.method = a;
        this.args = o;
        this.once = i;
        return this;
    };
    public run(...args) {
        if (null == this.method) return null;
        if (!this.caller || cc.isValid(this.caller)) {
            var e = this._id, t = this.method.apply(this.caller, this.args);
            this._id === e && this.once && this.recover();
            return t;
        }
        this.recover();
    };
    public runWith(e) {
        if (null == this.method) return null;
        if (!this.caller || cc.isValid(this.caller)) {
            var t = this._id;
            if (null == e) var a = this.method.apply(this.caller, this.args); else a = this.args || e.unshift ? this.args ? this.method.apply(this.caller, this.args.concat(e)) : this.method.apply(this.caller, e) : this.method.call(this.caller, e);
            this._id === t && this.once && this.recover();
            return a;
        }
        this.recover();
    };
    public clear() {
        this.caller = null;
        this.method = null;
        this.args = null;
        return this;
    };
    public recover() {
        if (this._id > 0) {
            this._id = 0;
            Handler._pool.push(this.clear());
        }
    };

    static create(t, a, o?, i?) {
        void 0 === o && (o = null);
        void 0 === i && (i = true);
        if (Handler._pool.length) {
            return Handler._pool.pop().setTo(t, a, o, i);
        } else {
            return new Handler(t, a, o, i);
        }
    };
}
